package com.itheima.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.Dto.SetmealDto;
import com.itheima.config.R;
import com.itheima.pojo.Category;
import com.itheima.pojo.Dish;
import com.itheima.pojo.Setmeal;
import com.itheima.pojo.SetmealDish;
import com.itheima.service.CategoryService;
import com.itheima.service.SetmealDishService;
import com.itheima.service.SetmealService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * 套餐管理
 */
@RestController
@RequestMapping("/setmeal")
public class SetmealController {

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealDishService setmealDishService;


    /**
     * 分页查询 模糊查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){

        // 模糊查询的条件
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name),Setmeal::getName,name);

        // 分页查询和 模糊查询
        Page<Setmeal> setmealPage = new Page<>(page,pageSize);
        setmealService.page(setmealPage,wrapper);

        //封装所有数据的分页
        Page<SetmealDto> SetmealDtoPage = new Page<>();


        // 把setmealPage数据源 复制 到 SetmealDtoPage空分页中 后续操作SetmealDtoPage分页
        BeanUtils.copyProperties(setmealPage,SetmealDtoPage);

        // 获取分页后的 一面数据
        List<Setmeal> records = setmealPage.getRecords();

        // 存储拷贝数据源后的对象
        List<SetmealDto> list = new ArrayList<>();

        // 循环一条数据的每个字段
        for (Setmeal record : records) {

            // 获取每条数据中的id
            Long id = record.getCategoryId();
            // 通过id去查询 分类表ID  分类表ID关联 套餐表CategoryId
            Category byId = categoryService.getById(id);

            // 给套餐分类赋值 这里可以给页面显示菜品分类
            SetmealDto setmealDto = new SetmealDto();
            setmealDto.setCategoryName(byId.getName());

            // setmealDto对象是空对象 所以需要把有数据的数据源复制过去
            BeanUtils.copyProperties(record,setmealDto);
            // 把数据添加到集合
            list.add(setmealDto);
        }

        // set到SetmealDto 表中
        SetmealDtoPage.setRecords(list);
        // 设置总数
        SetmealDtoPage.setTotal(setmealPage.getTotal());
        return R.success(SetmealDtoPage);

    }

    /**
     * 新增
     * @param setmealDto
     * @return
     */
    @PostMapping
    @CacheEvict(value = "setmealCache",allEntries = true)
    public R<String> save(@RequestBody SetmealDto setmealDto){

        // 套餐表直接添加数据
        setmealService.save(setmealDto);

        // 获取setmealDto 中 setmealDishes所有的集合数据
        List<SetmealDish> dishList = setmealDto.getSetmealDishes();

        // 循环setmealDishes 中个索引的数据
        for (SetmealDish setmealDish : dishList) {

            // 新增的数据 关联主表的id 是空的所以 新增功能都要去set id的值
            Long id = setmealDto.getId();
            // 这个字段是空的 所以需要set
            setmealDish.setSetmealId(id);
            // 套餐菜品 添加setmealDishes里面的所有数据
            setmealDishService.save(setmealDish);
        }

        return R.success("保存套餐成功!!");
    }

    /**
     * 删除套餐
     * @param ids
     * @return
     */
    @Transactional
    @DeleteMapping
    @CacheEvict(value = "setmealCache",allEntries = true)
    public R<String> delete(@RequestParam List<Long> ids){

        // 判断的条件 删除集合ids  并且 Status是0   0 是停售 ，停售才能删除
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Setmeal::getId,ids).eq(Setmeal::getStatus,0);

        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,ids);

        setmealService.remove(wrapper);
        setmealDishService.remove(queryWrapper);

        return R.success("套餐删除成功");
    }

    /**
     *  状态修改
     * @param status 状态  0停售  1起售
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    public R<String> status(@PathVariable Integer status,@RequestParam List<Long> ids){

        // 循环前端提供的全部id
        for (Long id : ids) {

            Setmeal setmeal = new Setmeal();

            // 设置id 给下面修改 提供
            setmeal.setId(id);

            // 通过前端传递的状态修改
            setmeal.setStatus(status);

            // 这里修改会 自动找到这个对象中的id
            setmealService.updateById(setmeal);
        }

        return R.success("操作成功");
    }

    /**
     *  修改套餐的回显
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<SetmealDto> echo(@PathVariable Long id){

        // 套餐表id  关联 套餐菜品SetmealId
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,id);

        // 获取到套餐表信息
        Setmeal byId = setmealService.getById(id);

        // 获取到套餐菜品数据
        List<SetmealDish> list = setmealDishService.list(queryWrapper);

        // 创建中间dto类 这个类关联两个表  直接把查询两个的信息 赋值到这个类
        SetmealDto setmealDto = new SetmealDto();

        // 把从套餐表的数据拷贝到dto类
        BeanUtils.copyProperties(byId,setmealDto);

        // 把从套餐菜品数据 封装到 dto类  这样  dto类 两个表的数据都有了
        setmealDto.setSetmealDishes(list);

        return R.success(setmealDto);
    }

    /**
     *  修改套餐
     * @param setmealDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody SetmealDto setmealDto){

        // 直接根据setmealDto对象修改套餐表的数据  会自动根据setmealDto对象中的id修改
        setmealService.updateById(setmealDto);

        // 套餐表Id 和 套餐菜品关系的 SetmealId 对应
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SetmealDish::getSetmealId,setmealDto.getId());

        //  套餐菜品 修改之前 删掉
        setmealDishService.remove(wrapper);

        // 获取这个 setmealDishes 这个字段
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();

        // 循环setmealDishes 字段的所有属性
        for (SetmealDish setmealDish : setmealDishes) {

            // 修改的菜品  添加的菜品是没ID的    所以从主表  setmealDto对象拿ID
            setmealDish.setSetmealId(setmealDto.getId());

            // 因为数据直接删掉了  所以可以直接修改
            setmealDishService.save(setmealDish);
        }

        return R.success("修改套餐成功");
    }


    /**
     * APP端 分类里面  点击套餐查询出来的套餐
     * @param categoryId
     * @param status
     * @return
     */
    @GetMapping("/list")
    @Cacheable(value = "setmealCache",key = "#setmeal.categoryId + '_' + #setmeal.status")
    public R<List<Setmeal>> list(Long categoryId,Integer status){

        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Setmeal::getCategoryId,categoryId).eq(Setmeal::getStatus,status);

        List<Setmeal> list = setmealService.list(wrapper);

        return R.success(list);
    }


}

